﻿using System;
using System.Collections.Generic;
using System.Text;

namespace LibUpdate.Down
{
    /// <summary>
    /// 下载功能的控制器
    /// </summary>
    internal class DownControl
    {


        public DownControl()
        {
            init();
        }
        public DownControl(UpdateConfig config)
        {
            _Config = config;
            init();
        }

        public void init()
        {
            CloseDown = false;
            downfile = Get_DownFile();  
            downfile.config = _Config;
            downfile.DownProgressChange += new FileDownProgressChangedHandler(downfile_DownProgressChange);
            downfile.DownStatuesChange += new FileDownStatusChangedHandler(downfile_DownStatuesChange);

        }
        #region 属性


        /// <summary>
        /// 系统配置
        /// </summary>
        private UpdateConfig _Config;

        /// <summary>
        /// 基本配置
        /// </summary>
        public UpdateConfig Config
        {
            get { return _Config; }
            set { _Config = value; }
        }


        //是否终止下载
        internal bool CloseDown { get; set; }

        /// <summary>
        /// 下载驱动
        /// </summary>
        private IDownFile downfile;

        /// <summary>
        /// 当前下载的版本
        /// </summary>
        private Version _Update_ver;

        public Version Update_Ver
        {
            get { return _Update_ver; }

            set { _Update_ver = value; }
        }

        /// <summary>
        /// 当前下载版本中的文件序列
        /// </summary>
        private int _FileIndex;


        #endregion

        #region 事件
        /// <summary>
        /// 下载信息通知
        /// </summary>
        internal event FileDownStatusChangedHandler DownStatus;
        /// <summary>
        /// 下载进度通知
        /// </summary>
        internal event FileDownProgressChangedHandler DownProgress;
        /// <summary>
        /// 版本下载状态
        /// </summary>
        internal event VersionUpdateStatusChangedHandler VersionUpdateStatusChange;
        #endregion



        /// <summary>
        /// 获得服务器版本文件。保存到本地
        /// </summary>
        /// <returns>返回文件路径</returns>
        public void Get_Version()
        {
            File version = new File();
            version.Type = FileType.UpdateInfoFile;
            version.ActionType = ActionType.Update;
            version.FileName = Base.ServerVersion;

            downfile.BeginDown(version);

        }


        /// <summary>
        /// 下载当前版本的所有文件
        /// </summary>
        public void DownVerFile()
        {
            //获得当前升级版本
            if (null != _Update_ver)
            {
                downfile.Version = _Update_ver;

                //开始下载
                _FileIndex = 0;
                Down(_FileIndex);
            }
            else
            {
                throw new Exception("未指定需要下载的版本");
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="index">在文件列表中的序列</param>
        private void Down(int index)
        {
            _FileIndex = index;
            //如果不是文件列表末尾
            if (index < _Update_ver.FileList.Count)
            {
                File f = _Update_ver.FileList[index];
                //目录不下载
                if (f.Type != FileType.Directory)
                {
                    downfile.BeginDown(f);
                }
                else //如果是目录，则调整到下一个文件进行下载
                {
                    _FileIndex++;
                    Down(_FileIndex);
                }
            }
            else
            {
                //触发版本全部下载成功通知
                VersionUpdateStatusChangedEvent versionEvent = new VersionUpdateStatusChangedEvent();
                versionEvent.Version = _Update_ver;
                versionEvent.State = VersionDownState.EndDown;
                VersionUpdateStatusChange(versionEvent);
            }
        }



        /// <summary>
        /// 获得下载模式驱动
        /// </summary>
        /// <returns></returns>
        private IDownFile Get_DownFile()
        {
            IDownFile mydownfile;
            switch (_Config.DownProviderType)
            {
                case DownProviderType.Http:
                    mydownfile = new HttpDownFile();
                    break;
                case DownProviderType.Ftp:
                    mydownfile = new HttpDownFile();
                    break;
                case DownProviderType.Tcp:
                    mydownfile = new HttpDownFile();
                    break;
                case DownProviderType.Mail:
                    mydownfile = new HttpDownFile();
                    break;
                default:
                    mydownfile = new HttpDownFile();
                    break;
            }
            return mydownfile;
        }


        /// <summary>
        /// 下载进度通知
        /// </summary>
        private void downfile_DownProgressChange(FileDownProgressChangedEvent e)
        {
            e.FileIndex = _FileIndex;
            //将事件触发进度通知事件
            DownProgress(e);
        }

        /// <summary>
        /// 响应下载事件
        /// </summary>
        /// <param name="e"></param>
        private void downfile_DownStatuesChange(FileDownStatusChangedEvent e)
        {
            e.FileIndex = _FileIndex;
            if (e.State == FileDownState.End && e.File.Type != FileType.UpdateInfoFile)
            {
                //MD5校验
                FileMD5Check(e);
            }
            DownStatus(e);
            if (!CloseDown) //是否终止下载
            {
                //设定当前下载的文件在列表中的序列,获取升级文件失败，则不重试
              
                if (e.State == FileDownState.Error && e.File.Type != FileType.UpdateInfoFile)
                {
                      //重试处理
                        AgainDown(e);
                }
                else if (e.State == FileDownState.End && e.File.Type!=FileType.UpdateInfoFile)
                {
                    //下载下一个文件
                    Down(e.FileIndex + 1);
                }
            }
        }

        /// <summary>
        /// 是否重新下载
        /// </summary>
        private void AgainDown(FileDownStatusChangedEvent e)
        {
            if (e.File.TautologyCount < _Config.TautologyCount)
            {
                //重试下载
                e.State = FileDownState.Again;
                e.File.TautologyCount++;
                DownStatus(e);
                System.Threading.Thread.Sleep(6000);
                Down(e.FileIndex);
            }
            else
            {
                //重试失败，弹出版本更新失败通知
                VersionUpdateStatusChangedEvent versionEvent = new VersionUpdateStatusChangedEvent();
                versionEvent.Version = _Update_ver;
                versionEvent.State = VersionDownState.Err;
                VersionUpdateStatusChange(versionEvent);
            }
         
        }
        //对文件执行md5校验
        private bool FileMD5Check(FileDownStatusChangedEvent e)
        {
            e.File.MD5Check = Base.MD5Check(_Config.ApplictionPath + Base.UpdatePath + _Update_ver.Directory + e.File.Path + "\\" + e.File.FileName, e.File.MD5);
            return e.File.MD5Check;
        }
    }
}
